package cn.sciento.farm.devicemanager.service.impl;

import cn.sciento.farm.devicemanager.common.constant.DeviceConstant;
import cn.sciento.farm.devicemanager.common.constant.RedisConstant;
import cn.sciento.farm.devicemanager.common.constant.ResultConstant;
import cn.sciento.farm.devicemanager.common.util.BaseContextHandler;
import cn.sciento.farm.devicemanager.common.util.RedisUtil;
import cn.sciento.farm.devicemanager.dao.entity.DevCamera;
import cn.sciento.farm.devicemanager.dao.entity.TenantConfig;
import cn.sciento.farm.devicemanager.dao.mapper.CameraMapper;
import cn.sciento.farm.devicemanager.service.CameraService;
import cn.sciento.farm.devicemanager.service.TenantConfigService;
import cn.sciento.fluorite.api.device.config.StopVideoEncrypt;
import cn.sciento.fluorite.api.device.control.StartPTZ;
import cn.sciento.fluorite.api.device.control.StopPTZ;
import cn.sciento.fluorite.api.device.manage.AddDeviceApi;
import cn.sciento.fluorite.api.device.manage.DeleteDeviceApi;
import cn.sciento.fluorite.api.token.GetToken;
import cn.sciento.fluorite.api.weblive.GetPeriodAddress;
import cn.sciento.fluorite.api.weblive.OpenLive;
import cn.sciento.fluorite.constants.StatusConstant;
import cn.sciento.fluorite.response.AccessToken;
import cn.sciento.fluorite.response.BaseDeviceResponse;
import cn.sciento.fluorite.response.BasicResponse;
import cn.sciento.fluorite.response.WebLiveAddress;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.netty.util.internal.StringUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.List;

@Service
public class CameraServiceImpl implements CameraService {

    Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    RedisTemplate redisTemplate;

    @Value("${fluorite.appKey}")
    String defaultAppKey;

    @Value("${fluorite.appSecret}")
    String defaultAppSecret;

    @Autowired
    private CameraMapper cameraMapper;

    @Autowired
    private TenantConfigService tenantConfigService;


    public String refreshToken() {
        String tenantId = BaseContextHandler.getTenantId();
        if(StringUtils.isEmpty(tenantId)){
            tenantId = "base";
        }
        String redisToken = (String) RedisUtil.getCacheSimple(RedisConstant.FLUORITE_ACCESS_TOKEN+tenantId);
        if (StringUtils.isEmpty(redisToken)) {
            String appKey = defaultAppKey;
            String appSecret = defaultAppSecret;
            // 是否启动自家的系统
            if(!tenantId.equals("base")){
                TenantConfig tenantConfig = tenantConfigService.get(tenantId);
                if(tenantConfig != null){
                    if(StringUtils.isNotEmpty(tenantConfig.getYsAppKey())
                    && StringUtils.isNotEmpty(tenantConfig.getYsSecret())){
                        appKey = tenantConfig.getYsAppKey();
                        appSecret = tenantConfig.getYsSecret();
                    }
                }
            }
            logger.info(appKey + "---------" + appSecret);
            GetToken getToken = new GetToken(appKey, appSecret);
            BasicResponse<AccessToken> basicResponse = getToken.executeApi();
            if (basicResponse.getCode().equals(StatusConstant.OK)) {
                RedisUtil.putCacheStr(RedisConstant.FLUORITE_ACCESS_TOKEN+tenantId, basicResponse.getData().getAccessToken(), 3600L * 24 * 6);
                return basicResponse.getData().getAccessToken();
            } else {
                logger.error("获取萤石云token失败。" + basicResponse);
                return "";
            }
        } else {
            return redisToken;
        }
    }

    @Override
    public int insert(DevCamera devCamera,String validateCode) throws UnsupportedEncodingException {

            //使用自家的账号的摄像头，使用设备序列号和验证码
            String deviceSerial = devCamera.getDeviceSerial();
            QueryWrapper cameraWrapper = new QueryWrapper<DevCamera>()
                    .eq("device_serial", devCamera.getDeviceSerial())
                    .eq("channel_no", devCamera.getChannelNo());
            int deviceNumber = cameraMapper.selectCount(cameraWrapper);
            if (deviceNumber > 0) {
                return ResultConstant.CAMERA_REPEAT.getCode();
            }
            AddDeviceApi addDeviceApi = new AddDeviceApi(refreshToken(), devCamera.getDeviceSerial(), validateCode);
            BasicResponse<BaseDeviceResponse> basicResponse = addDeviceApi.executeApi();
            logger.info(basicResponse.toString());
//            //TODO 这里根据实际情况进行编写
            if (basicResponse.getCode().equals(StatusConstant.OK) || basicResponse.getCode().equals(StatusConstant.MYSELF_DEVICE_ADD)) {
                //开通直播
                String source = deviceSerial + ":" + devCamera.getChannelNo();
                OpenLive openLive = new OpenLive(refreshToken(), URLEncoder.encode(source, "utf8"));
                BasicResponse liveResponse = openLive.executeApi();
                logger.info(liveResponse.toString());


                //关闭加密,没有判断成功失败
                StopVideoEncrypt videoEncrypt = new StopVideoEncrypt(refreshToken(), deviceSerial, validateCode);
                BasicResponse encryptRepResponse = videoEncrypt.executeApi();
                logger.info(encryptRepResponse.toString());


            } else {
                return 0;
            }

            int result = cameraMapper.insert(devCamera);
        return result;
    }

    @Override
    public int updateById(DevCamera devCamera) {
        return cameraMapper.updateById(devCamera);
    }

    @Override
    public DevCamera getById(long id) {
        return cameraMapper.selectById(id);
    }

    @Override
    public List<DevCamera> getByAreaId(long id) {
        QueryWrapper queryWrapper = new QueryWrapper<DevCamera>();
        queryWrapper.eq("area_id",id);
        List<DevCamera> devCameraList = cameraMapper.selectList(queryWrapper);
        return devCameraList;
    }

    @Override
    public int deleteById(long id) {
        DevCamera deviceCamera = cameraMapper.selectById(id);
        if (deviceCamera == null) {
            return ResultConstant.NULL_PARAMETER.getCode();
        }
        DeleteDeviceApi deviceApi = new DeleteDeviceApi(refreshToken(), deviceCamera.getDeviceSerial());
        BasicResponse<BaseDeviceResponse> basicResponse = deviceApi.executeApi();
        int count = 0;
        count = cameraMapper.deleteById(id);
        return count;
    }

    @Override
    public int deleteByArea(Integer areaId, Integer landId) {
        QueryWrapper queryWrapper = new QueryWrapper<DevCamera>();
        if(landId != null){
            queryWrapper.eq("land_id",landId);
        }else if(areaId != null) {
            queryWrapper.eq("area_id",areaId);
        }else {
            throw new NullPointerException("基地和地块id不能同时为空");
        }
        return cameraMapper.delete(queryWrapper);
    }

    @Override
    public WebLiveAddress getLiveById(long id) {
        DevCamera deviceCamera = cameraMapper.selectById(id);

        if (deviceCamera == null) {
            return null;
        }

        GetPeriodAddress periodAddress = new GetPeriodAddress(refreshToken(), deviceCamera.getDeviceSerial(), deviceCamera.getChannelNo(), 0);
        BasicResponse<WebLiveAddress> basicResponse = periodAddress.executeApi();
        if (basicResponse.getCode().equals(StatusConstant.OK)) {
            return basicResponse.getData();
        }
        return null;
    }

    @Override
    public int controlPTZ(long id, int direction,int speed) {
        DevCamera deviceCamera = cameraMapper.selectById(id);
        if (deviceCamera == null) {
            return 0;
        }
        if(direction <0){
            StopPTZ stopPTZ = new StopPTZ(refreshToken(), deviceCamera.getDeviceSerial(),
                    deviceCamera.getChannelNo(),
                    -direction-1
            );
            BasicResponse<BaseDeviceResponse> stopResp = stopPTZ.executeApi();
            if(stopResp.getCode().equals(StatusConstant.OK)){
                return 1;
            }
            return 0;
        }else {
            StartPTZ startPTZ = new StartPTZ(
                    refreshToken(),
                    deviceCamera.getDeviceSerial(),
                    deviceCamera.getChannelNo(),
                    direction,
                    speed
            );
            BasicResponse<BaseDeviceResponse> basicResponse = startPTZ.executeApi();
            if (basicResponse.getCode().equals(StatusConstant.OK)) {
                return 1;
            }
            return 0;
        }
    }

    @Override
    public DevCamera getBySerial(String deviceSerial, int channelNo) {
        QueryWrapper queryWrapper = new QueryWrapper<DevCamera>();
        queryWrapper.eq("device_serial",deviceSerial);
        queryWrapper.eq("channel_no",channelNo);
        DevCamera devCamera = cameraMapper.selectOne(queryWrapper);
        return devCamera;
    }
}
